﻿using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using BattleFury.Lib.Extensions;
using BattleFury.Lib.Input;
using Microsoft.Xna.Framework;

namespace BattleFury.Lib.Controls
{
	public class Selector
		: Control
	{
		public static string PartLeftArrow = "ArrowLeft";
		public static string PartLeftArrowHighlighted = "ArrowLeftHighlighted";
		public static string PartLeftArrowClicked = "ArrowLeftClicked";
		public static string PartRightArrow = "ArrowRight";
		public static string PartRightArrowHighlighted = "ArrowRightHighlighted";
		public static string PartRightArrowClicked = "ArrowRightClicked";
		public static string PartBorderLeft = "ProgressBarLeft";
		public static string PartBorderCenter = "ProgressBarCenter";
		public static string PartBorderRight = "ProgressBarRight";

		private Part _leftArrowPart;
		private Part _leftArrowHighlightPart;
		private Part _leftArrowClickPart;
		private string _leftArrowState;

		private Part _rightArrowPart;
		private Part _rightArrowHighlightPart;
		private Part _rightArrowClickPart;
		private string _rightArrowState;

		private Part _leftBorderPart;
		private Part _centerBorderPart;
		private Part _rightBorderPart;

		private List<string> Items
		{
			get
			{
				return ItemsSource.Split(',').ToList();
			}
		}

		public int SelectedIndex { get; set; }
		public string ItemsSource { get; set; }
		public Color ForegroundColor { get; set; }
		public Color BorderColor { get; set; }

		public int Count
		{
			get { return Items.Count; }
		}

		public string SelectedValue
		{
			get { return Items[SelectedIndex]; }
		}

		public Selector()
		{
			_leftArrowState = "Normal";
			_rightArrowState = "Normal";
		}

		public override void Deserialize(XElement element, object callingObject)
		{
			base.Deserialize(element, callingObject);

			SelectedIndex = element.GetInt("SelectedIndex");
			ItemsSource = element.GetString("ItemsSource");
			ForegroundColor = element.GetColor("ForegroundColor", Color.Black);
			BorderColor = element.GetColor("BorderColor", Color.White);
		}

		public override void Update(GameTime gameTime)
		{
			if (_leftArrowPart == null)
			{
				_leftArrowPart = Skin[PartLeftArrow];
				_rightArrowPart = Skin[PartRightArrow];
				_leftArrowHighlightPart = Skin[PartLeftArrowHighlighted];
				_rightArrowHighlightPart = Skin[PartRightArrowHighlighted];
				_leftArrowClickPart = Skin[PartLeftArrowClicked];
				_rightArrowClickPart = Skin[PartRightArrowClicked];

				_leftBorderPart = Skin[PartBorderLeft];
				_centerBorderPart = Skin[PartBorderCenter];
				_rightBorderPart = Skin[PartBorderRight];
			}

			var input = RenderEngine.Get().Input;

			_leftArrowState = "Normal";
			var leftArrowRect = new Rectangle((int)Position.X, (int)Position.Y, (int)_leftArrowPart.Width, (int)_leftArrowPart.Height);
			if (input.Mouse.CurrentBounds.Intersects(leftArrowRect))
			{
				_leftArrowState = "Highlighted";
				if (input.Mouse.IsMouseButtonHeld(MouseButtons.Left))
				{
					_leftArrowState = "Clicked";
				}
				if (input.Mouse.IsMouseButtonPressed(MouseButtons.Left))
				{
					SelectedIndex--;
					if (SelectedIndex < 0) SelectedIndex = Count - 1;
				}
			}

			var innerWidth = (Size.X - (_leftArrowPart.Width + _rightArrowPart.Width) + _leftArrowPart.Width);
			_rightArrowState = "Normal";
			var rightArrowRect = new Rectangle((int)(Position.X + innerWidth), (int)Position.Y, (int)_rightArrowPart.Width, (int)_rightArrowPart.Height);
			if (input.Mouse.CurrentBounds.Intersects(rightArrowRect))
			{
				_rightArrowState = "Highlighted";
				if (input.Mouse.IsMouseButtonHeld(MouseButtons.Left))
				{
					_rightArrowState = "Clicked";
				}
				if (input.Mouse.IsMouseButtonPressed(MouseButtons.Left))
				{
					SelectedIndex++;
					if (SelectedIndex >= Count) SelectedIndex = 0;
				}
			}
		}

		public override void Draw(GameTime gameTime)
		{
			var leftArrowRect = new Rectangle((int)Position.X, (int)Position.Y, (int)_leftArrowPart.Width, (int)_leftArrowPart.Height);
			var leftArrowPart = _leftArrowPart;
			if (_leftArrowState == "Highlighted") leftArrowPart = _leftArrowHighlightPart;
			if (_leftArrowState == "Clicked") leftArrowPart = _leftArrowClickPart;
			SpriteBatch.Draw(Texture, leftArrowRect, leftArrowPart.SourceBounds, Color.White);

			var innerWidth = (Size.X - (_leftArrowPart.Width + _rightArrowPart.Width) + _leftArrowPart.Width);
			var rightArrowRect = new Rectangle((int)(Position.X + innerWidth), (int)Position.Y, (int)_rightArrowPart.Width, (int)_rightArrowPart.Height);
			var rightArrowPart = _rightArrowPart;
			if (_rightArrowState == "Highlighted") rightArrowPart = _rightArrowHighlightPart;
			if (_rightArrowState == "Clicked") rightArrowPart = _rightArrowClickPart;
			SpriteBatch.Draw(Texture, rightArrowRect, rightArrowPart.SourceBounds, Color.White);


			SpriteBatch.Draw(Texture, new Vector2(Position.X + leftArrowPart.Width, Position.Y), _leftBorderPart.SourceBounds, BorderColor);

			var innerBorderWidth = (innerWidth - (_leftBorderPart.Width + _rightBorderPart.Width) - _leftArrowPart.Width);
			for (var i = 0; i < innerBorderWidth; i += _centerBorderPart.Width)
			{
				SpriteBatch.Draw(Texture, new Vector2(Position.X + leftArrowPart.Width + i + _leftBorderPart.Width, Position.Y), _centerBorderPart.SourceBounds, BorderColor);
			}

			SpriteBatch.Draw(Texture, new Vector2(Position.X + innerBorderWidth + _centerBorderPart.Width + _leftArrowPart.Width, Position.Y), _rightBorderPart.SourceBounds, BorderColor);

			var textSize = Font.MeasureString(SelectedValue);
			var textPosition = new Vector2(Position.X + _leftArrowPart.Width + (_leftBorderPart.Width / 4), Position.Y + ((Size.Y / 2) - (textSize.Y / 2)));
			SpriteBatch.DrawString(Font, SelectedValue, textPosition + Vector2.One, Color.Black.WithOpacity(0.5f));
			SpriteBatch.DrawString(Font, SelectedValue, textPosition, ForegroundColor);
		}
	}
}